package com.ctsi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctsi.common.util.Search;
import com.ctsi.core.common.exception.ServiceException;
import com.ctsi.core.common.util.$;
import com.ctsi.core.database.util.PageUtil;
import com.ctsi.core.fastdfs.core.FastdfsTemplate;
import com.ctsi.core.web.util.OssUtil;
import com.ctsi.system.entity.Material;
import com.ctsi.system.enums.MaterialExceptionType;
import com.ctsi.system.mapper.MaterialMapper;
import com.ctsi.system.service.IMaterialService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 素材表 服务实现类
 * </p>
 *
 * @version 1.0
 * @author: wang xiao xiang
 * @date: 2021/8/19 10:18
 */
@Service
@RequiredArgsConstructor
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements IMaterialService {

    private final FastdfsTemplate fastDfsUtil;

    @Override
    public IPage<Material> listPage(Material material, Search search) {
        LambdaQueryWrapper<Material> queryWrapper = Wrappers.<Material>lambdaQuery()
                .like($.isNotBlank(search.getKeyword()), Material::getName, search.getKeyword());
        if ($.isNotNull(material)) {
            queryWrapper.eq($.isNotEmpty(material.getMaterialGroupId()), Material::getMaterialGroupId, material.getMaterialGroupId());
            queryWrapper.eq($.isNotEmpty(material.getType()), Material::getType, material.getType());
        }
        queryWrapper.orderByDesc(Material::getCreateTime);
        return this.baseMapper.selectPage(PageUtil.getPage(search), queryWrapper);
    }

    @Override
    public Map<String, Object> upload(String groupId, String materialId, MultipartFile file, boolean isThumb) {
        // 上传素材
//        Map<String, Object> map = uploadOss(file);
        Map<String, Object> map = new HashMap<>();
        try {
            map = fastDfsUtil.upload(file);
            String url = $.toStr(map.get("url"));
            String fileName = $.toStr(map.get("fileName"));
            String ossType = $.toStr(map.get("ossType"));
            String extName = null;
            if ($.isNotBlank(fileName)) {
                // 获取文件扩展名
                extName = FilenameUtils.getExtension(fileName);
            }
            Long mId = 0L;
            // 操作入库
            if (!isThumb) {
                // 上传成功后记录入库
                mId = this.setMaterial(file, groupId, url, fileName, extName, ossType);
            } else {
                mId = this.setMaterialThumb(materialId, url);
            }
            map.put("materialId", mId);
        } catch (IOException e) {
            log.error("文件上传服务器异常", e);
        }
        return map;
    }

//    @Override
//    public Map<String, Object> uploadIO(String groupId, String materialId, File file, boolean isThumb) {
//        Map<String, Object> map = new HashMap<>();
//        try {
//            map = fastDfsUtil.upload(file);
//
//            String url = $.toStr(map.get("url"));
//            String fileName = $.toStr(map.get("fileName"));
//            String ossType = $.toStr(map.get("ossType"));
//            String extName = null;
//            if ($.isNotBlank(fileName)) {
//                // 获取文件扩展名
//                extName = FilenameUtils.getExtension(fileName);
//            }
//            Long mId = 0L;
//            // 操作入库
//            if (!isThumb) {
//                // 上传成功后记录入库
//                mId = this.setMaterial(file, groupId, url, fileName, extName, ossType);
//            } else {
//                mId = this.setMaterialThumb(materialId, url);
//            }
//            map.put("materialId", mId);
//        } catch (Exception e) {
//        }
//        return map;
//    }


//    /**
//     * 上传素材至OSS，包括图片和视频
//     *
//     * @param file 上传文件
//     * @return Map　文件参数
//     */
//    private Map<String, Object> uploadOss(MultipartFile file) {
//        Set set = setService.get(SetConstant.MATE_OSS_USED);
//        if ($.isEmpty(set) || $.isNull(set.getValue())) {
//            throw new ServiceException("您还未配置OSS存储服务!");
//        }
//
//        String ossType = set.getValue();
//
//        // 根据默认的OSS查询OSS参数
//        Set setValue = setService.get(set.getValue());
//        OssSetting ossSetting = $.requireNotNull($.toBean(JSON.parseObject(setValue.getValue()), OssSetting.class));
//        OssProperties ossProperties = $.copyProperties(ossSetting, OssProperties.class);
//
//        if ($.isEmpty(ossProperties)) {
//            throw new ServiceException("OSS存储服务参数不正确!");
//        }
//
//        // 初始化OssTemplate
//        OssTemplate ossTemplate = new OssTemplate(ossProperties);
//        ossTemplate.afterPropertiesSet();
//
//        // 拼装文件名
//        String fileName = UUID.randomUUID().toString().replace("-", "")
//                + StringPool.DOT + FilenameUtils.getExtension(file.getOriginalFilename());
//        Map<String, Object> resultMap = new HashMap<>(4);
//
//        try {
//            // 上传文件
//            ossTemplate.putObject(ossProperties.getBucketName(), fileName, file.getInputStream(), file.getSize(), file.getContentType());
//            // 生成URL
//            String url = "https://" + ossProperties.getCustomDomain() + StringPool.SLASH + fileName;
//            // 自定义返回报文
//            resultMap.put("ossType", ossType);
//            resultMap.put("fileName", fileName);
//            resultMap.put("url", url);
//        } catch (Exception e) {
//            log.error("上传失败", e);
//            throw new ServiceException(MaterialExceptionType.MATERIAL_UPLOAD_FAIL.getMessage() + e.getMessage());
//        }
//        return resultMap;
//    }

    @Override
    public boolean moveGroup(List<String> ids, String groupId) {
        // 批量更换指定ID的分组ID
        ids.forEach(id -> {
            this.update(Wrappers.<Material>lambdaUpdate()
                    .set(Material::getMaterialGroupId, groupId).eq(Material::getId, id));
        });
        return Boolean.TRUE;
    }

    /**
     * 将上传成功的文件记录入库
     *
     * @param file 　文件
     * @param url  　返回的URL
     */
    private Long setMaterial(MultipartFile file, String groupId, String url, String fileName, String extName, String ossType) {
        Material material = new Material();
        String original = file.getOriginalFilename();
        String originalName = FilenameUtils.getName(original);
        material.setName(originalName);
        material.setUrl(url);
        material.setFileName(fileName);
        material.setMaterialGroupId($.toLong(groupId, 0L));
        material.setFileSize($.toInt(file.getSize()));
        material.setType($.toStr(OssUtil.getFileType(original)));
        material.setExtName(extName);
        material.setOssType(ossType);
        this.save(material);
        return material.getId();
    }

//    private Long setMaterial(File file, String groupId, String url, String fileName, String extName, String ossType) {
//        Material material = new Material();
//        material.setName(file.getName());
//        material.setUrl(url);
//        material.setFileName(fileName);
//        material.setMaterialGroupId($.toLong(groupId, 0L));
//        material.setFileSize($.toInt(file.length()));
//        material.setType($.toStr(OssUtil.getFileType(file.getAbsolutePath())));
//        material.setExtName(extName);
//        material.setOssType(ossType);
//        this.save(material);
//        return material.getId();
//    }

    /**
     * 设置缩略图
     *
     * @param materialId 素材ID
     * @param url        缩略图地址
     * @return 主键ID
     */
    private Long setMaterialThumb(String materialId, String url) {
        if ($.isAnyBlank(materialId, url)) {
            throw new ServiceException(MaterialExceptionType.MATERIAL_ID_NOT_EXIST.getMessage());
        }
        this.update(Wrappers.<Material>lambdaUpdate()
                .set(Material::getThumbUrl, url).eq(Material::getId, materialId));
        return $.toLong(materialId);
    }
}

